﻿using System.Web;
using System.Web.Mvc;
using System;
using System.Web.Routing;

namespace WebApp
{
    public class FilterConfig
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
        }

        /// http://blog.ploeh.dk/2009/12/01/GlobalErrorHandlinginASP.NETMVC/
        /// 
        /*
         * When a Controller action is invoked, this actually happens through an IActionInvoker. 
         * The default ControllerActionInvoker is responsible for gathering the list of IExceptionFilters, 
         * so the first thing we can do is to derive from that and override its GetFilters method
         * 王相备注： 我想这篇文章肯定是写在MVC可以添加全局过滤器之前，所以才会有下面的两个类
         */
    }

    public class ErrorHandlingActionInvoker : ControllerActionInvoker
    {
        private readonly IExceptionFilter filter;

        public ErrorHandlingActionInvoker(IExceptionFilter filter)
        {
            if (filter == null)
            {
                throw new ArgumentNullException("filter");
            }
            this.filter = filter;
        }

        protected override FilterInfo GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
        {
            var filterInfo = base.GetFilters(controllerContext, actionDescriptor);
            filterInfo.ExceptionFilters.Add(this.filter);
            return filterInfo;
        }
    }

    public class ErrorHandlingControllerFactory : DefaultControllerFactory
    {
        public override IController CreateController(RequestContext requestContext,string controllerName)
        {
            var controller = base.CreateController(requestContext, controllerName);
            var c = controller as Controller;
            if (c != null)
            {
                c.ActionInvoker = new ErrorHandlingActionInvoker(new HandleErrorAttribute());
            }
            return controller;
        }
    }
}